package se.gala.users;

import se.gala.api.CommandRequestor;
import se.gala.api.MessageBroadcaster;
import se.gala.core.Agora;
import se.gala.core.GameId;
import se.gala.core.abstracts.AbstractGame;
import se.gala.money.MoneyInt;
import se.gala.utils.GGObject;
import se.gala.wallet.BalanceTypes;
import se.gala.wallet.BalanceUpdateTypes;
import se.gala.wallet.InsufficientFundsException;
import se.gala.wallet.WalletFacade;

public class Player extends GGObject implements BalanceUpdateObserver, CommandRequestor {

	private PlayerBalance balance;
	private String username;
	private MessageBroadcaster broadcaster;
	
	public static final WalletFacade wallet = WalletFacade.getInstance();

	private Player(String username) {
		// TODO extend implementation of Player()
		log("Player object, created wiht Username: " + username);
		this.username = username;
		broadcaster = Agora.getBroadcaster();
	}
	
	public String getUsername() {
		return username;
	}

	public static Player initiatePlayer(String externalId) {
		final Player p = new Player(externalId);
		p.balance = wallet.getPlayerBalanceById(externalId);
		p.balance.addObserver(p);
		// TODO implement logic to parse that info
		// Object info = wallet.getPlayerInfoById(externalId);
		return p;
	}

	public PlayerBalance getBalance() {
		return balance;
	}
	
	public void registerBet(BalanceTypes balanceType,
			MoneyInt amount, AbstractGame game) throws InsufficientFundsException {
		registerGambleActivity(balanceType, amount, BalanceUpdateTypes.BET, game.getGameId());
	}
	
	public void registerWin(BalanceTypes balanceType, GameId game) {
		try {
//			log("WIN: " + amount);
			registerGambleActivity(
					balanceType, 
					balance.moneyIntFactory(game
							.getGame()
							.getWinning()),
					BalanceUpdateTypes.WIN, 
					game);
			game.setEndGame();
		} catch (InsufficientFundsException e) {
			/* it's very unlikely that we'd hit InsufficientFundsException upon a win */
			e.printStackTrace();
		}
	}

	protected synchronized void registerGambleActivity(BalanceTypes balanceType,
			MoneyInt amount, BalanceUpdateTypes updateType, GameId game) throws InsufficientFundsException {
		amount.setNegative(!updateType.isBalanceIncrease());
		switch (balanceType) {
		case CashPlayable:
			balance.updateRealCashBalance(amount);
			break;
		case BonusPlayable:
		default:
			// IDEA BonusBalancePlayable
			break;
		}
	}

	@Override
	public void update(PlayerBalanceObservable o, MoneyInt newAmount) {
		if (broadcaster == null) {
			return;
		}
		broadcaster.sendCommand(Agora.getConstructor().doConstructCommand(this));
	}
}
